package com.thug.engine;

import org.anddev.andengine.entity.scene.Scene;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;

public abstract class BaseGameEntity {
	
	public enum EntityType {
		ET_PLAYER,
		ET_BOT,
		ET_WALL,
		ET_OBSTACLE,
		ET_GOLD,
		ET_SOUNDER,
		ET_UNKNOWN

	}

	protected EntityType mEntityType;
	private boolean mActive;
	private int mLayer;
	private int mID; // every entity has a unique identifying number
	private static int mNextValidID = 0; // this is the next valid ID. Each time
											// a BaseGameEntity is instantiated
											// this value is updated
	private Object mUserData;

	public BaseGameEntity() {
		mID = mNextValidID;
		mNextValidID++;
		mEntityType = EntityType.ET_UNKNOWN;
		mActive = true;
		mLayer = 0;
	}

	public int getID() {
		return mID;
	}

	/**
	 * initialize the game object
	 */
	public abstract void init();

	/**
	 * attach the game objects to the scene
	 * 
	 * @param scene
	 */
	public abstract void attach(final Scene scene);

	/**
	 * detach the game object from the scene
	 * 
	 * @param scene
	 */
	public abstract void detach(final Scene scene);

	/**
	 * update object behavior must be called once on each frame
	 * 
	 * @param elapsedTime
	 */
	public abstract void update(final float elapsedTime);

	/**
	 * Called when two fixtures begin to touch. colliding entity
	 */
	public abstract void beginContact(final Body bodyA, final Body bodyB,
			final Vector2 normal, final Vector2[] points);

	/**
	 * Called when two fixtures cease to touch.
	 */
	public abstract void endContact(final Body bodyA, final Body bodyB,
			final Vector2 normal, final Vector2[] points);

	/**
	 * set all internal references to null
	 */
	public abstract void dispose();

	/**
	 * change the object layer
	 */
	public void changeLayer(int newLayerID) {
		mLayer = newLayerID;
	}

	/**
	 * return the current layer id of the object
	 */
	public int getLayerID() {
		return mLayer;
	}

	/**
	 * return true if the object is in active state
	 */
	public boolean isActive() {
		return mActive;
	}

	/**
	 * set the current state of the object
	 */
	public void setActive(boolean active) {
		mActive = active;
	}

	/**
	 * return entity type
	 */
	public EntityType getType() {
		return mEntityType;
	}


	/**
	 * return X axis position of the entity in scene space
	 * @return
	 */
	public abstract float getX();
	
	/**
	 * return Y axis position of the entity in scene space
	 * @return
	 */
	public abstract float getY();
	
	/**
	 * returns entity rotation in degree
	 * @return
	 */
	public abstract float getRotation();
	
	/**
	 * attach extra info to the  entity
	 * @param userData
	 */
	public final void setUserData(Object userData) {
		mUserData = userData;
	}
	
	/**
	 * retrieve extra info from the entity
	 * @return
	 */
	public final Object getUserData() {
		return mUserData;
	}
	
}
